package com.yumo.kangchenjunga.company;

import java.io.IOException;
import java.util.List;
import java.util.NoSuchElementException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.web.PageableDefault;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.yumo.kangchenjunga.common.ExistsAssociationException;
import com.yumo.kangchenjunga.exception.controller.HttpBadRequestException;
import com.yumo.kangchenjunga.exception.controller.HttpNotFoundException;
import com.yumo.kangchenjunga.security.CustomUserDetails;
import com.yumo.kangchenjunga.user.NoSuchUserException;

@RestController
@RequestMapping("/api/v1/companies")
public final class CompanyController {

	@Autowired
	private CompanyService service;

	@GetMapping("/{id}")
	public CompanyVo queryById(@PathVariable int id) throws HttpNotFoundException {
		try {
			return service.queryById(id);
		} catch (NoSuchCompanyException e) {
			throw HttpNotFoundException.build(e, "企业 [ id: %d ] 不存在。", id);
		}
	}

	@GetMapping("/")
	public Iterable<CompanyVo> list() {
		return service.list();
	}

	@GetMapping(path = "/", params = { "paged" })
	public Page<CompanyVo> page(
			@PageableDefault(page = 0, size = 10, sort = "id", direction = Direction.DESC) Pageable pageable) {
		return service.page(pageable);
	}

	@PostMapping("/service/query")
	public Page<CompanyVo> query(@RequestBody CompanyVo company,
			@PageableDefault(page = 0, size = 10, sort = "id", direction = Direction.DESC) Pageable pageable) {
		return service.query(company, pageable);
	}

	@PostMapping("/")
	public CompanyVo create(@RequestBody CompanyVo company) throws HttpNotFoundException {
		try {
			return service.create(company);
		} catch (NoSuchCompanyException e) {
			throw HttpNotFoundException.build(e, "企业 [ id: %d ] 不存在。", company.id);
		}
	}

	@DeleteMapping("/{id}")
	public void delete(@PathVariable int id) throws HttpBadRequestException {
		try {
			service.delete(id);
		} catch (ExistsAssociationException e) {
			throw HttpBadRequestException.build("企业下存在权益。");
		}
	}

	@PutMapping("/{id}")
	public CompanyVo modify(@PathVariable int id, @RequestBody CompanyVo company)
			throws HttpNotFoundException, HttpBadRequestException {
		if (id == company.id) {
			try {
				return service.modify(id, company);
			} catch (NoSuchCompanyException e) {
				throw HttpNotFoundException.build(e, "企业 [ id: %d ] 不存在。", id);
			}
		}

		throw HttpBadRequestException.build("The id in the path(%d) and body(%d) does not match.", id, company.id);
	}

	@GetMapping("/stores/{storeId}")
	public StoreVo queryStoreById(@PathVariable int storeId) throws HttpNotFoundException {
		try {
			return service.queryStoreById(storeId);
		} catch (NoSuchStoreException e) {
			throw HttpNotFoundException.build(e, "门店 [ id: %d ] 不存在。", storeId);
		}
	}

	@GetMapping("/getStoreByCompanyId/{companyId}")
	public List<StoreVo> queryStoreByCompanyId(@PathVariable int companyId) {
		return service.queryStoreByCompanyId(companyId);
	}

	@GetMapping(path = "/stores/", params = { "paged" })
	public Page<StoreVo> pageStore(
			@PageableDefault(page = 0, size = 10, sort = "id", direction = Direction.DESC) Pageable pageable) {
		return service.pageStore(pageable);
	}

	@GetMapping(path = "/stores/query")
	public Page<StoreVo> queryStore(@AuthenticationPrincipal CustomUserDetails currentUser, HttpServletRequest request,
			@PageableDefault(page = 0, size = 10, sort = "id", direction = Direction.DESC) Pageable pageable) {
		StoreVo store = new StoreVo();
		store.name = request.getParameter("name");
		store.companyId = currentUser.getCompanyId();
		return service.queryStores(store, pageable);
	}

	@PostMapping("/stores/")
	public StoreVo createStore(@RequestBody StoreVo store) {
		return service.createStore(store);
	}

	@DeleteMapping("/stores/{storeId}")
	public void deleteStore(@PathVariable int storeId) {
		service.deleteStore(storeId);
	}

	@PutMapping("/stores/{storeId}")
	public StoreVo modify(@PathVariable int storeId, @RequestBody StoreVo store)
			throws HttpNotFoundException, HttpBadRequestException {
		if (storeId == store.id) {
			try {
				return service.modifyStore(storeId, store);
			} catch (NoSuchStoreException e) {
				throw HttpNotFoundException.build(e, "门店 [ id: %d ] 不存在。", storeId);
			}
		}

		throw HttpBadRequestException.build("The id in the path(%d) and body(%d) does not match.", storeId, store.id);
	}

	@PostMapping("/{companyId}/admin/vc")
	public String verificationCode(@AuthenticationPrincipal CustomUserDetails currentUser,
			@PathVariable int companyId) throws HttpNotFoundException {
		try {
			return service.sendVerificationCode(companyId, currentUser.getId());
		} catch (NoSuchCompanyException e) {
			throw HttpNotFoundException.build(e, "企业 [ id: %d ] 不存在。", companyId);
		}
	}

	@PostMapping("/{companyId}/admin/password")
	public void changePassword(@AuthenticationPrincipal CustomUserDetails currentUser, @PathVariable int companyId,
			@RequestParam String verificationCode, @RequestParam String newPassword) throws HttpNotFoundException {
		try {
			service.changeAdminPassword(companyId, currentUser.getId(), verificationCode, newPassword);
		} catch (NoSuchUserException e) {
			throw HttpNotFoundException.build(e, "企业 [ id: %d ] 未找到管理员用户。", companyId);
		}
	}

	@ExceptionHandler(Exception.class)
	public void handler(Exception e, HttpServletResponse response) throws IOException {
		if (e instanceof DataIntegrityViolationException) {
			response.sendError(400, "手机号重复。");
		} else if (e instanceof NoSuchElementException) {
			response.sendError(404);
		} else {
			response.sendError(500);
		}
	}

	@GetMapping(path = "/category/")
	public List<CompanyCategoryEntity> listCategory() {
		return service.listCategory();
	}

	@GetMapping(path = "/category/", params = { "paged" })
	public Page<CompanyCategoryEntity> pageCategory(
			@PageableDefault(page = 0, size = 10, sort = "name") Pageable pageable) {
		return service.pageCategory(pageable);
	}

	@PostMapping("/category/")
	public CompanyCategoryEntity createCategory(@RequestBody CompanyCategoryEntity entity) {
		return service.createCategory(entity);
	}

	@DeleteMapping("/category/{categoryId}")
	public void deleteCategory(@PathVariable int categoryId) {
		service.deleteCategory(categoryId);
	}

}
